<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>拓朴图demo2</title>
    <link rel="stylesheet" href="css/googleapis.css">
    <link rel="stylesheet" href="css/demo2.css">
    <style>
        .none{
            display: none;
        }
        .cursor{
            cursor: pointer;
        }
    </style>
</head>
<body>
<div class="container">
    <h2>拓朴图demo2</h2>
    <div id="graphic"></div>
</div>
<!--<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>-->
</body>
</html>
<script src="../../js/jQuery/jquery.min.js"></script>
<script src="js/d3.v3.min.js"></script>
<script>
    /**
     * 此为d3 v3版本的demo
     *
     */



    try {
        // Configure graphics 配置图形
        var width = 1000,
            height = 800;

        var circleWidth = 5,
            charge = -75,
            gravity = 0.1;

        var palette = {
            "lightgray": "#D9DEDE",
            "gray": "#C3C8C8",
            "mediumgray": "#536870",
            "orange": "#BD3613",
            "purple": "#595AB7",
            "yellowgreen": "#738A05"
        };

        var colorChoose = [
            // "#cfe2f3",
            // "#a4c2f4",
            // "#6fa8dc",
            // "#ffe599",
            // "#ffd966",
            // "#ffff00",
            // "#f4cccc",
            // "#ea9999",
            // "#ff0000"

            "#CFECF9",
            "#B6E5F9",
            "#9FE3F9",
            "#87DBF9",
            "#75D1F9",
            "#65C3F9",
            "#52B7F9",
            "#36A8F9",
            "#1e81f9"






            // "#00f9e4",
            // "#00d7f9",
            // "#00abf9",
            // "#007ff9",
            // "#003df9",
            // "#0400f9",
            // "#3000f9"
        ];
        var linkVal = [];
        for(var i=0;i<255;i++){
            linkVal.push(parseInt(Math.random()*1000))
        }

        // Generate test data 生成测试数据
        var nodes = [];
        var numNodes = 125;
        for (var x = 0; x < numNodes; x++) {
            var targetAry = [];
            var connections = (Math.round(Math.random() * 5));
            for (var y = 0; y < connections; y++) {
                targetAry.push(Math.round(Math.random() * numNodes))
            }
            nodes.push({
                id: x,
                name: "Node " + x,
                target: targetAry,
                value:15
            })
        }


        // Create the links array from the generated data 从生成的数据创建链接数组
        var links = [];
        for (var i = 0; i < nodes.length; i++) {
            if (nodes[i].target !== undefined) {
                for (var j = 0; j < nodes[i].target.length; j++) {
                    links.push({
                        source: nodes[i],
                        target: nodes[nodes[i].target[j]],
                        // value:parseInt(Math.random()*1000)
                        value:linkVal[i]
                    })
                }
            }
        }
        var zoom = d3.behavior.zoom()
            .scaleExtent([0.2, 4])
            .on("zoom", zoomed);

        // Create SVG 创建SVG
        var fdGraph = d3.select('#graphic')
            .append('svg')
            .attr('width', width)
            .attr('height', height)
            .call(zoom)
            .on("dblclick.zoom",null);

        var mapG = fdGraph.append("g")
            .attr("id","forceGroup");
        function zoomed(d) {
            // mapG.attr("transform",
            //     'translate('+width/2+','+height/2+'),' +
            //     'scale('+d3.event.scale+')translate('+-width/2+','+-height/2+')');
            mapG.attr("transform",
                'translate('+d3.event.translate+') scale('+d3.event.scale+')');
        }
        // Create the force layout to calculate and animate node spacing 创建力布局计算和动画节点间距
        var forceLayout = d3.layout.force()
            .nodes(nodes)
            .links([])
            .gravity(gravity)
            .charge(charge)
            .size([width, height]);

        // Create the SVG lines for the links 为链接创建SVG行
        // var link = fdGraph
        var link = mapG
            .selectAll('.lineG').data(links).enter()
            .append("g")
            .attr("class","lineG")
            .append('line')
            // .attr('stroke', palette.gray)
            .attr('stroke', function (d,i) {
                var customlinkVal = linkVal;
                var sortLinkVal = customlinkVal.sort(function (a,b) {
                    return a-b;
                });
                // console.log(sortLinkVal);
                // console.log(Math.round(colorChoose.length*sortLinkVal.indexOf(d.value)/sortLinkVal.length));
                return colorChoose[Math.round(colorChoose.length*sortLinkVal.indexOf(d.value)/sortLinkVal.length)]
            })
            .attr('stroke-width', 1)
            .attr('class', function(d, i) {
                // Add classes to lines to identify their from's and to's 将类添加到行中以标识它们的
                var theClass ='line_' + d.source.id + ' line';
                if(d.target !== undefined) {
                    theClass += ' to_' + d.target.id
                }
                return  theClass + " cursor"
            })
            .on("mouseover",function (d) {
                d3.select(this)
                    // .attr('stroke', palette.orange)
                    .attr('stroke-width', 2);
                d3.select($(this).next()[0])
                    .attr("class","lineText")
            })
            .on("mouseout",function (d) {
                d3.select(this)
                    // .attr('stroke', palette.lightgray)
                    .attr('stroke-width', 1);
                d3.select($(this).next()[0])
                    .attr("class","lineText none")
            })
            .on("click",function (d) {
                console.log(d);
                console.log(this);
            });
        var lineText = mapG.selectAll(".lineG")
            .append("text")
            .attr("class","lineText none")
            .attr('font-size', '14')
            .attr('font-weight', 'bold')
            .attr("dy","1.5em")
            .text(function (d) {
                return d.value
            });

        // Create the SVG groups for the nodes and their labels 为节点及其标签创建SVG组
        // var node = fdGraph
        var node = mapG
            .selectAll('circle').data(nodes).enter()
            .append('g')
            .attr('id', function(d) { return 'node_' + d.id })
            .attr('class', 'node')
            .on('mouseover', function(d) {
                /**
                 * When mousing over a node, make the label bigger and bold
                 * and revert any previously enlarged text to normal
                 * 当点击一个节点时，使标签更大、更醒目。
                 *  并将任何先前放大的文本恢复为正常
                 *
                 */
                // d3.selectAll('.node').selectAll('text')
                //     .attr('font-size', '12')
                //     .attr('font-weight', 'normal');

                // Highlight the current node 突出当前节点
                d3.select(this).select('text')
                    .attr('font-size', '16')
                    .attr('font-weight', 'bold')
                    .attr("class","");

                d3.select(this).select('circle')
                    .attr('stroke-width', '2')
                    .attr('stroke',palette.lightgray);

                // Hightlight the nodes that the current node connects to 高亮当前节点连接到的节点
                for(var i = 0; i < d.target.length; i++) {
                    d3.select('#node_' + d.target[i]).select('text')
                        .attr('font-size', '14')
                        .attr('font-weight', 'bold')
                        .attr("class","");
                }

                // Reset and fade-out the unrelated links 重置和淡出无关链接
                // d3.selectAll('.line')
                //     // .attr('stroke', palette.lightgray)
                //     .attr('stroke-width', 1);

                for(var x = 0; x < links.length; x++) {
                    if(links[x].target !== undefined) {
                        if(links[x].target.id === d.id) {
                            // Highlight the connections to this node 突出显示与此节点的连接
                            d3.selectAll('.to_' + links[x].target.id)
                                // .attr('stroke', palette.orange)
                                .attr('stroke-width', 2);

                            // Highlight the nodes connected to this one 突出显示连接到这个节点的节点
                            d3.select('#node_' + links[x].source.id).select('text')
                                .attr('font-size', '14')
                                .attr('font-weight', 'bold')
                                .attr("class","");
                        }
                    }
                }

                // Highlight the connections from this node 突出显示此节点的连接
                d3.selectAll('.line_' + d.id)
                    // .attr('stroke', palette.purple)
                    .attr('stroke-width', 2)
            })
            .on("mouseout",function (d) {
                d3.select(this).select('text')
                    // .attr('font-size', '16')
                    // .attr('font-weight', 'bold')
                    .attr("class","none");

                d3.select(this).select('circle')
                    // .removeAttribute("stroke-width")
                    // .removeAttribute("stroke")
                    .attr('stroke-width', '')
                    .attr('stroke',"");
                // Hightlight the nodes that the current node connects to
                for(var i = 0; i < d.target.length; i++) {
                    d3.select('#node_' + d.target[i]).select('text')
                        // .attr('font-size', '14')
                        // .attr('font-weight', 'bold')
                        .attr("class","none");
                }

                // Reset and fade-out the unrelated links
                d3.selectAll('.line')
                    // .attr('stroke', palette.lightgray)
                    .attr('stroke-width', 1);

                for(var x = 0; x < links.length; x++) {
                    if(links[x].target !== undefined) {
                        if(links[x].target.id === d.id) {
                            // Highlight the connections to this node
                            d3.selectAll('.to_' + links[x].target.id)
                                // .attr('stroke', palette.orange)
                                .attr('stroke-width', 1);

                            // Highlight the nodes connected to this one
                            d3.select('#node_' + links[x].source.id).select('text')
                                // .attr('font-size', '14')
                                // .attr('font-weight', 'bold')
                                .attr("class","none");
                        }
                    }
                }
            })
            .call(forceLayout.drag);

        // Create the SVG circles for the nodes 为节点创建SVG圆
        node.append('circle')
            .attr('cx', function(d) {
                return d.x
            })
            .attr('cy', function(d) {
                return d.y
            })
            .attr('r', circleWidth)
            .attr('fill', function(d, i) {
                // Color 1/3 of the nodes each color 每个颜色的节点颜色1/3
                // Depending on the data, this can be made more meaningful 根据数据，这可以变得更有意义。
                if (i < (numNodes / 3)) {
                    return palette.orange
                } else if (i < (numNodes - (numNodes / 3))) {
                    return palette.purple
                }
                return palette.yellowgreen
            })
            .attr("class","cursor")
            // .on("click",function (d) {
            //     console.log(d);
            // })
            .on("dblclick",function (d) {
                // d3.selectAll("svg").remove();//删除功能
                console.log(d);
                console.log(nodes.length);
/*

                nodes.push({
                    id: nodes.length+1,
                    name: "Node " + nodes.length+1,
                    target: d,
                    value:15
                });
                linkVal.push(500);
                links.push({
                    source: d,
                    target: nodes[nodes.length-1],
                    // value:parseInt(Math.random()*1000)
                    value:500
                })
*/

            });

        // Create the SVG text to label the nodes 创建SVG label the nodes to the text
        node.append('text')
            .text(function(d) {
                return d.name
            })
            .attr('font-size', '12')
            .attr("dy","1.5em")
            .attr("class","none");

        // Animate the layout every time tick 每时每刻动画布局
        forceLayout.on('tick', function(e) {
            // Move the nodes base on charge and gravity 基于电荷和重力移动节点
            node.attr('transform', function(d, i) {
                return 'translate(' + d.x + ', ' + d.y + ')'
            });
            //文字调整
            lineText
                .attr('dy', function(d){
                    if(d.target != undefined){
                        return (d.target.y-d.source.y)/2+d.source.y
                    }else {
                        return 0
                    }
                })
                .attr('dx',function(d){
                    if(d.target != undefined){
                        return (d.target.x-d.source.x)/2+d.source.x
                    }else {
                        return 0
                    }
                });
            // Adjust the lines to the new node positions 将线路调整到新的节点位置
            link
                .attr('x1', function(d) {
                    return d.source.x
                })
                .attr('y1', function(d) {
                    return d.source.y
                })
                .attr('x2', function(d) {
                    if (d.target !== undefined) {
                        return d.target.x
                    } else {
                        return d.source.x
                    }
                })
                .attr('y2', function(d) {
                    if (d.target !== undefined) {
                        return d.target.y
                    } else {
                        return d.source.y
                    }
                })
        })
            .drag().on("dragstart",function (d) {
            //拖拽开始后设定被拖拽对象固定
            // d.fixed = true;
            d3.layout.force().stop();
            d3.event.sourceEvent.stopPropagation();
        })
            .on("dragend",function (d,i) {
                //拖拽结束后变为原来的颜色
                // d3.select(this).style("fill",color(i));
                d3.layout.force().tick();
                d3.layout.force().resume();
            })
            .on("drag",function (d) {
                //拖拽中对象变为黄色
                // d3.select(this).style("fill","yellow");
                d.px += d3.event.dx;
                d.py += d3.event.dy;
                d.x += d3.event.dx;
                d.y += d3.event.dy;
                d3.layout.force().tick();
            });


        // Start the initial layout 开始初始布局
        forceLayout.start();

    } catch (e) {
        alert(e)
    }
</script>